﻿using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.WebTesting;
using System.ComponentModel;

namespace PEWay.VisualStudio.Extensibility
{
    /// <summary>
    /// Thanks to http://weblogs.asp.net/pgreborio/archive/2005/09/22/425775.aspx
    /// </summary>
    [DisplayName("Extract Query String Paramter")]
    [Description("Extracts a query string parameter value.")]
    public class ExtractQueryStringParamter : ExtractionRule
    {
        private string _parameterName = string.Empty;

        [Description("Type a name for the QueryString parameter.")]
        public string ParameterName
        {
            get
            {
                if (string.IsNullOrEmpty(_parameterName))
                    _parameterName = "ID";

                return _parameterName;
            }
            set
            {
                if (value != string.Empty)
                    _parameterName = value;
            }
        }

        public override string ContextParameterName
        {
            get
            {
                if (string.IsNullOrEmpty(base.ContextParameterName))
                    return "EntityID";
                
                return base.ContextParameterName;
            }
            set
            {
                base.ContextParameterName = value;
            }
        }


        public override void Extract(object sender, ExtractionEventArgs e)
        {
            e.Success = true;

            if (e.Response.ContentType.Contains("text/html"))
                ExtractFromHtml(e);
            else // if (e.Response.ContentType.Contains("text/plain"))
                ExtractFromAsyncPostback(e);

            if (e.Success)
                e.Message = "Query string parameter extracted.";
            else
                e.Message = "No query string parameter extracted.";
        }

        private void ExtractFromHtml(ExtractionEventArgs e)
        {
            if (e.Response.ResponseUri.Query.Length == 0)
                return;

            string[] queryStrings = e.Response.ResponseUri.Query.Substring(1).Split('&');
            foreach (string item in queryStrings)
            {
                string[] itemParts = item.Split('=');
                string key = itemParts[0];
                string value = itemParts[1];

                if (key.Equals(this.ParameterName, StringComparison.OrdinalIgnoreCase))
                {
                    WriteQueryStringToContext(e, value);
                    return;
                }
            }

        }

        private void ExtractFromAsyncPostback(ExtractionEventArgs e)
        {

            StringComparison compType;


            if (!e.Response.BodyString.Contains("pageRedirect"))
            {
                return;
            }

            string[] bodyParts = e.Response.BodyString.Split('?');
            if (bodyParts == null || bodyParts.Length < 2)
            {
                return;
            }
            string queryStringParamtersString = bodyParts[1];
            string[] queryStringParamters = queryStringParamtersString.Split('&');
            if (queryStringParamters == null || queryStringParamters.Length == 0)
            {
                return;
            }

            QueryStringParameterCollection queryStringParameterCollection = new QueryStringParameterCollection();
            foreach (string queryStringItem in queryStringParamters)
            {
                string[] queryStringItemParts = queryStringItem.Split('=');
                string key = queryStringItemParts[0];
                string value = queryStringItemParts[1].Replace('|', ' ');
                queryStringParameterCollection.Add(new QueryStringParameter(key, value));
            }

            foreach (QueryStringParameter parameter in queryStringParameterCollection)
            {
                if (parameter.Name.Equals(this.ParameterName, StringComparison.OrdinalIgnoreCase))
                {
                    WriteQueryStringToContext(e, parameter.Value);
                    return;
                }
            }

        }

        private void WriteQueryStringToContext(ExtractionEventArgs e, string parameterValue)
        {
            e.Success = true;

            if (!string.IsNullOrEmpty(ContextParameterName))
            {
                // Check if the context variable exists
                if (!e.WebTest.Context.ContainsKey(ContextParameterName))
                    e.WebTest.Context.Add(ContextParameterName, parameterValue);
                else
                    e.WebTest.Context[ContextParameterName] = parameterValue;
            }
        }
    }
}